<?php
session_start();
$_SESSION['a'] = 'dsdww';
//启用session时会发生数据库延时故障

//去掉数据库，使用缓存来处理


//父进程在整个生命周期运行，未释放sql链接，所以在子进程都查询都被锁定

function get_tasks() {
	$con = mysql_connect('127.0.0.1', 'root', '');
	$db = mysql_selectdb('proc', $con);
	$tasks = array();
	$r = mysql_query("select id,func,params,state from cmd");
	if ($r) {
		while ($row = mysql_fetch_object($r)) {
			$tasks[] = $row;
		}
	}
	mysql_close($con);
	return $tasks;
}

function get_one_task() {
	$con = mysql_connect('127.0.0.1', 'root', '');
	$db = mysql_selectdb('proc', $con);
	$tasks = array();
	$r = mysql_query("select id,func,params from cmd where state=0 limit 0,1");
	if ($r) {
		while ($row = mysql_fetch_object($r)) {
			$task = $row;
			mysql_close($con);
			return $task;
		}
	}
}

function lock_one_task($id) {
	$con = mysql_connect('127.0.0.1', 'root', '');
	$db = mysql_selectdb('proc', $con);
	$r = mysql_query(sprintf("update cmd set state=1 where id='%s'", $id));
}
/**
 *  获取未输出结果的数据
 */

function get_remain_tasks() {
	$con = mysql_connect('127.0.0.1', 'root', '');
	$db = mysql_selectdb('proc', $con);
	$tasks = array();
	$r = mysql_query("select id,func,params from cmd where state !=3 limit 0,1");
	if ($r) {
		while ($row = mysql_fetch_object($r)) {
			$tasks[] = $row;
		}
	}
	mysql_close($con);
	return $tasks;
}

function get_task_result() {
	$con = mysql_connect('127.0.0.1', 'root', '');
	$db = mysql_selectdb('proc', $con);
	static $i = 0;
	$resluts = array();
	$ids = array();
	//这一步会被死锁
	
	//查询次数过多，需要一个延时
	
	//var_dump($i++);
	$r = mysql_query("select id,result,callback from cmd where state=2");
	if ($r) {
		while ($row = mysql_fetch_object($r)) {
			$resluts[] = $row;
			$ids[] = $row->id;
		}
	}
	mysql_close($con);
	clean_tasks($ids);
	return $resluts;
}
///最后任务清理逻辑

function clean_tasks($ids_array) {
	$con = mysql_connect('127.0.0.1', 'root', '');
	$db = mysql_selectdb('proc', $con);
	if (!empty($ids_array)) {
		$ids = implode(',', $ids_array);
		mysql_query(sprintf("update cmd set state=3 where id in (%s)", $ids));
	}
	mysql_close($con);
}

function parse_result($results) {
	if (!empty($results)) {
		foreach ($results as $r) {
			proc($r->callback, $r->result);
		}
	}
}

function proc($func, $params) {
	return call_user_func($func, json_decode($params, TRUE));
}

function callback($result) {
	//result is array
	
	//var_dump($result);
	
}

function Sleeper($mSec) {
	if (!function_exists('socket_create')) {
		die("Please enable extension php_sockets.dll");
	}
	static $socket = FALSE;
	if ($socket === FALSE) {
		$socket = array(
			socket_create(AF_INET, SOCK_RAW, 0)
		);
	}
	$pSock = $socket;
	$uSex = $mSec * 1000;
	$read = $write = array();
	$tSex = 0;
	socket_select($read, $write, $pSock, $tSex, $uSex);
	return TRUE;
}
//$tasks=get_one_task();

//var_dump($tasks);

//remove_task(1);

//需要将session传入proc_handler.php

//会不会2个条件同时不成立呢！！！处于中间的状态  解决

//$a=10;

//var_dump(empty($b=$a+1));

//

//现在的问题是一个进程只处理一个任务就退出，好浪费
//是否输出交给另外一个进程来处理呢
//session_id传递 存在大问题 大量演示 外部脚本似乎取不到session内容
while (TRUE) {
	//这边缺少一个锁
	
	//var_dump($task);
	$task = get_one_task();
	//在这两部都需要一个延时操作
	
	//循环内部只有在任务分发完毕后才去取结果
	var_dump($task);
	if (!$task) {
		$results = get_task_result();
		$remainTasks = get_remain_tasks();
		//var_dump($results);
		Sleeper(1000);
		var_dump(time());
		//var_dump($results);
	}
	if (!is_object($task) && empty($results) && empty($remainTasks)) break;
	if ($task) {
		lock_one_task($task->id);
		//每派生一个进程都需要花费很长时间
		$cmd = 'e:\easyphp\php\php.exe ' . 'proc_handler.php ' . $task->id . " " . $task->func . " " . $task->params . ' ' . session_id();
		//虽然任务是异步触发了，但是其不会立即执行，其会在主进程执行完毕后才执行？？？？？这个很奇怪 执行了 但是内部时序好像有问题
		//打开的第一个是同步执行的 其他在在主进程执行完毕会OK
		pclose(popen("start /B " . $cmd, "r"));
		//var_dump(get_tasks());
		
	}
	if (!empty($results)) {
		//parse the result;
		parse_result($results);
		echo "-----------------------------------------<br/>";
	}
}
//$i=5;

//while($i>0){

//	//window not support start

//	$cmd='e:\easyphp\php\php.exe '.'proc_handler.php';

//	pclose(popen("start /B ". $cmd, "r"));

//	$i--;

//	echo $i;

//}

?>